package GUI;

import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.swing.Box;
import javax.swing.JFrame;

import Plants.PowerPlant;
import Plants.PowerPlantListener;
import SmartGrid.SmartGrid;

public class GraphMatrix extends JFrame{

	Box currentBox;
	Box body;
	Map<String, Graph> graphs;
	
	SmartGrid smartgrid;
	
	public GraphMatrix()
	{
        super("Graph Matrix");
        graphs = new HashMap<String, Graph>();
		super.setLayout(new BorderLayout(4,4));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
		body = Box.createVerticalBox();
		super.add(body, BorderLayout.EAST);		
		initFrameProperties();
	}
	
	public GraphMatrix(SmartGrid smartgrid)
	{
		this();
		this.smartgrid = smartgrid;
		listen();
	}
	
	private void initFrameProperties()
	{
		pack();
		setVisible(true);
		super.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		WindowListener windowListener = new WindowAdapter()
		{
		   // anonymous WindowAdapter class
		   public void windowClosing ( WindowEvent w )
		   {
			   closeWindow();
		   } // end windowClosing
		};// end anonymous class
		this.addWindowListener( windowListener );
	}
	
	/**
	 * Subscribe to changes in power plant's supply and demand
	 */
	private void listen()
	{
		Iterator<PowerPlant> plants = smartgrid.allPlants.values().iterator();
		while(plants.hasNext())
		{
			PowerPlant plant = plants.next();
			final Graph g = new Graph(plant.getName());
			plant.getListeners().add(new PowerPlantListener()
			{

				@Override
				public synchronized void PowerPlantResponsibilitiesChanged(PowerPlant p) {
					g.addPoint("Responsibility", p.getResponsibilities());
				}

				@Override
				public synchronized void PowerPlantSupplyChanged(PowerPlant p) {
					g.addPoint("Supply", p.getAvailableEnergy());
				}

				@Override
				public void PowerPlantRepaint(PowerPlant p) {
					
				}
				
			});
			addGraph(g);
		}
	}
	
	public void closeWindow()
	{
		GraphMatrix.this.setVisible(false);
		GraphMatrix.this.dispose();
	}
	
	/**
	 * Adds a graph to the graph matrix
	 * @param g
	 */
	public void addGraph(Graph g)
	{
		if(graphs.size() % 3 == 0)
		{
			currentBox = Box.createHorizontalBox();
			body.add(currentBox);
		}
		currentBox.add(g);
		graphs.put(g.getTitle(), g);
		validate();
		pack();
	}
	
	/**
	 * Removes a graph from this graph matrix
	 * @param g
	 */
	public void removeGraph(Graph g)
	{
		g.getParent().remove(g);
		graphs.remove(g.getTitle());
		validate();
		pack();
	}
	
	public static void main(String[] args)
	{
		GraphMatrix gm = new GraphMatrix();
		gm.addGraph(new Graph("Test"));
		gm.addGraph(new Graph("Test2"));
		gm.addGraph(new Graph("Test3"));
		gm.addGraph(new Graph("Test4"));
		gm.addGraph(new Graph("Test5"));
		gm.addGraph(new Graph("Test6"));
	}
	
}

